/**
* File: War3Source_Solaris.sp
* Description: Solaris the Sunfang for war3source!
* Author(s): Revan
*/

/* ADVERTS
* YOUR AD HERE
*
* YOUR AD HERE
*
* Ok lets stop that stuff cO
*/

//race based on luna moonfang
/*
#pragma semicolon 1
#include <sourcemod>
#include <sdktools>

#include "W3SIncs/War3Source_Interface"
//#include "W3SIncs/mana"
#include "revantools.inc"
#include "W3SIncs/mana"
*/
//
#pragma semicolon 1
#include <sourcemod>
#undef REQUIRE_EXTENSIONS
#include "W3SIncs/mana"
#define REQUIRE_EXTENSIONS
#include <sdktools>
#include "sdkhooks"
#include "W3SIncs/War3Source_Interface"
public W3ONLY(){}



// War3Source stuff...

new iManaValue[MAXPLAYERS]=0;
new bool:bExtension=false;

// Upper Mleko Testing

new thisRaceID;

new Float:SunLanceChance[6] = { 0.0, 0.50, 0.60, 0.70, 0.75, 0.80 };
new Float:GlaiveChance[6] = { 0.0, 0.15, 0.20, 0.22, 0.25, 0.30 };
new Float:IncendiumRange[6] = { 0.0, 80.0, 140.0, 160.0, 200.0, 260.0};

new Float:SunRange[6] = {0.0, 200.0, 250.0, 300.0, 350.0, 410.0};
new SunMinDmg[6] = {0,14,20,24,30,35};
new SunMaxDmg[6] = {0,20,32,40,45,50};

new String:firesnd[]   = "npc/strider/fire.wav";
new String:zitsch[] = "weapons/fx/nearmiss/bulletltor06.wav";
new String:charge[] = "weapons/explode3.wav";
new String:ultimate[] = "ambient/explosions/explode_8.wav";

new SKILL_1, SKILL_2, SKILL_3, ULT;
new BeamSprite,HaloSprite,FireSprite,LaserSprite,CoreSprite;

//new SunCharge[MAXPLAYERS];
new bool:bSunShoot[MAXPLAYERS];
new bool:bIncendium[MAXPLAYERS];

new Handle:cvar_solarispush = INVALID_HANDLE;
new Handle:cvar_solariscd = INVALID_HANDLE;
public Plugin:myinfo = 
{
	name = "War3Source Race - Solaris",
	author = "Revan",
	description = "Solaris the Sunfang for war3source!",
	version = "1.0.0.0",
	url = "www.wcs-lagerhaus.de"
};

public OnPluginStart()
{
	//^CreateTimer(1.0,DisplayCharge,_,TIMER_REPEAT); //create the timer for the energy display
	if(War3_GetGame()!=Game_CS)
	{
		//the entities used by this race are only avaible in css..
		//someone needs to make a engine that uses predcrabs CEntity framework to add a similar entity to the game xD
		SetFailState("This game is not supported by this Race - Sorry!");
	}
	if(GetExtensionFileStatus("w3mana.ext") == 1)
	{
		PrintToServer("[Solaris] Extension found, using w3mana system");
		bExtension=true;
	}
	cvar_solarispush=CreateConVar("war3_solaris_ultimate_push","1.2","[W3S] Solaris - Push force of the Ultimate.");
	cvar_solariscd=CreateConVar("war3_solaris_ultimate_cooldown","10","[W3S] Solaris - Ultimate cooldown time in seconds.");
	//RegAdminCmd("war3_solaris", Command_GiveGem, ADMFLAG_RCON, "[Coder] Testing Command");
	CreateTimer(1.0,UpdateMana,_,TIMER_REPEAT);
}

public Action:Command_GetMode(args){
	if(bExtension==false) {
		PrintToServer("[Solaris] W3Mana ext. not found using standalone mana system instead...");
	}
	else {
		PrintToServer("[Solaris] Using W3Mana extension.");
	}
}

public APLRes:AskPluginLoad2Custom(Handle:myself,bool:late,String:error[],err_max)
{
	MarkNativeAsOptional("W3GetMana");
	MarkNativeAsOptional("W3SetMana");
	MarkNativeAsOptional("W3ToggleMana");
	MarkNativeAsOptional("W3SetManaRegen");
	return APLRes_Success;
}

public OnRaceChanged(client,oldrace,newrace)
{
    //SunCharge[client]=0;
	bIncendium[client]=false;
	if(newrace==thisRaceID) {
		//W3ToggleMana(client,thisRaceID,true);
		//W3SetManaRegen(client,1);
	}
}

public Action:UpdateMana(Handle:h,any:data)
{
	if(bExtension==false) 
	{
		for(new i=1;i<=MaxClients;i++)
		{
			if(ValidPlayer(i,true))
			{
				if(War3_GetRace(i)==thisRaceID)
				{
					if(iManaValue[i]<=100) 
					{
						//using hint engine instead of this...PrintCenterText(i,"Mana: %i/100",iManaValue[i]);
						//W3Hint(i,HINT_LOWEST,1.0,"SunEnergy: %i/100",iManaValue[i]); // ^W3Hint
						iManaValue[i]++;
						
					}
				}	
				if (iManaValue[i]<=100 && iManaValue[i]>=10)
				{
					W3Hint(i,HINT_LOWEST,1.0,"SunEnergy: %i/100",iManaValue[i]); // ^W3Hint
				}
				if (iManaValue[i]>30)
				{
					decl Float:OwnerPos[3];
					GetClientAbsOrigin(i, OwnerPos);
					new skill_level = War3_GetSkillLevel( i, thisRaceID, SKILL_3 );
					new Float:maxdist = IncendiumRange[skill_level];
					for (new t = 1; t <= MaxClients; t++)
					{
						if(ValidPlayer(t,true) && GetClientTeam(t) != GetClientTeam(i)) 
						{
							decl Float:TargetPos[3];
							GetClientAbsOrigin(t, TargetPos);
							if (GetVectorDistance(OwnerPos, TargetPos) <= maxdist)
							{
								TargetPos[2]-=50.0;
								PushClientToVector( t, TargetPos, 0.1 );
								W3FlashScreen( t, RGBA_COLOR_RED, 3.0);
								TargetPos[2]+=80.0;
								TE_SetupBeamRingPoint(TargetPos, 10.0, 15.0, BeamSprite, HaloSprite, 0, 10, 1.0, 5.0, 0.0, {255,120,120,255}, 10, 0);
								TE_SendToAll();
							}
						}
					}
				}
			}
		}
	}
}

/* Mleko
public Action:DisplayCharge(Handle:timer,any:userid)
{
	for(new i=0;i<MAXPLAYERS;i++)
	{
		if(ValidPlayer(i,true)) 
		{
			if(War3_GetRace(i) == thisRaceID)
			{
				new mana = W3GetMana(i);
				if(mana>30)
				{

				}
			}
		}
	}
}
Mleko */
public OnMapStart()
{
	//precache models and sounds for later use
	War3_PrecacheSound( firesnd );
	War3_PrecacheSound( zitsch );
	War3_PrecacheSound( charge );
	War3_PrecacheSound( ultimate );
	HaloSprite = PrecacheModel( "materials/sprites/halo01.vmt" );   
	BeamSprite = PrecacheModel( "materials/sprites/plasma.vmt" );
	FireSprite = PrecacheModel( "materials/sprites/flamelet5.vmt" );
	LaserSprite = PrecacheModel( "materials/sprites/bluelaser1.vmt" );
	CoreSprite = PrecacheModel( "materials/sprites/orangecore1.vmt" );
	
	PrecacheModel("materials/sprites/light_glow02_add_noz.vmt");
	PrecacheModel("materials/effects/strider_bulge_dudv.vmt");
	PrecacheModel("materials/particle/fire.vmt");
	if(bExtension==false && GetExtensionFileStatus("w3mana.ext") == 1) {
		PrintToServer("[Anivia] Extension found, using w3mana system");
		bExtension=true;
	}
	//if(thisRaceID>0)
	//W3ManaSystem(thisRaceID,true);
}

public OnWar3PluginReady()
{
	//simple race registry
	thisRaceID = War3_CreateNewRace( "Solaris the Sunfang - Solrider", "solaris" );
	
	SKILL_1 = War3_AddRaceSkill( thisRaceID, "Sun Lance", "Collects the energy of the Sun into you Lance and release it in one shoot(ability to release, costs 10 Sun Energy)", false, 5 );	
	SKILL_2 = War3_AddRaceSkill( thisRaceID, "Fire Glaive", "Use your Fire Glaive to deal some AoE Damage to your victims!", false, 5 );	
	SKILL_3 = War3_AddRaceSkill( thisRaceID, "Incendium", "Solaris is allways surrounded with a heatwave to simply disort enemyes around her.", false, 5 );
	ULT = War3_AddRaceSkill( thisRaceID, "The Sun", "Create's a sun that pushes and damages all near enemyes(costs 20 Sun Energy)", true, 5 );
	
	W3SkillCooldownOnSpawn( thisRaceID, ULT, 8.0, true );
	
	War3_CreateRaceEnd( thisRaceID );
	// Mleko // W3ManaSystem(thisRaceID,true);
}



public OnWar3EventDeath(victim,attacker)
{
	if(ValidPlayer(victim,false))
	// Mleko W3SetMana(victim,10);
	{
		if(bExtension) W3SetManaRegen(victim,0);
	}
}

public OnW3TakeDmgBullet( victim, attacker, Float:damage )
{
	if( IS_PLAYER( victim ) && IS_PLAYER( attacker ) && victim > 0 && attacker > 0 && attacker != victim ) //check player's
	{
		new vteam = GetClientTeam( victim );
		new ateam = GetClientTeam( attacker );
		if( vteam != ateam ) //check player teams
		{
			new race_attacker = War3_GetRace( attacker );
			new skill_level = War3_GetSkillLevel( attacker, thisRaceID, SKILL_1 );
			new skill_level2 = War3_GetSkillLevel( attacker, thisRaceID, SKILL_2 );
			if( race_attacker == thisRaceID ) //check attacker skills...
			{
				if(!W3HasImmunity( victim, Immunity_Skills )) {
					if( skill_level2 > 0 && GetRandomFloat( 0.0, 1.0 ) <= GlaiveChance[skill_level2]) //similar the same as above
					{
						new Float:start_pos[3];
						new Float:target_pos[3];
						GetClientAbsOrigin(attacker,start_pos);
						GetClientAbsOrigin(victim,target_pos);
						target_pos[2]+=50.0;
						start_pos[0]+=40.0, start_pos[1]+=40.0;
						TE_SetupBeamPoints(start_pos, target_pos, LaserSprite, HaloSprite, 0, 100, 2.0, 15.0, 1.0, 0, 1.0, {255,55,15,255}, 100);
						TE_SendToAll();
						start_pos[0]-=40.0, start_pos[1]-=40.0;
						TE_SetupBeamPoints(start_pos, target_pos, LaserSprite, HaloSprite, 0, 100, 2.0, 15.0, 1.0, 0, 1.0, {255,0,0,255}, 100);
						TE_SendToAll();
						start_pos[0]-=80.0, start_pos[1]-=80.0;
						TE_SetupBeamPoints(start_pos, target_pos, LaserSprite, HaloSprite, 0, 100, 2.0, 15.0, 1.0, 0, 1.0, {255,55,15,255}, 100);
						TE_SendToAll();
						
						new Float:size1;
						new Float:size2;
						new Float:delay;
						new Float:maxdist;
						for(new i=1;i<=6;i++)
						{							
							size1 += 19.0;
							size2 += GetRandomFloat(20.0,40.0);
							TE_SetupBeamRingPoint(target_pos,size1,size2,FireSprite,HaloSprite,0,28,0.5,13.0,0.0,{255,60,60,255},9,0);
							TE_SendToAll(delay);
							delay += 0.5;
							maxdist = size2;
						}
						PrintHintText(attacker,"Fire Glaive used on your victim!");
						for (new i = 1; i <= MaxClients; i++) {
							if(ValidPlayer(i,true) && GetClientTeam(i) != GetClientTeam(attacker)) {
								decl Float:TargetPos[3];
								GetClientAbsOrigin(i, TargetPos);
								new Float:Distance = GetVectorDistance(target_pos, TargetPos);
								if (Distance <= maxdist) {
									War3_DealDamage( i, GetRandomInt(6,10), attacker, DMG_BURN, "fireglaive" ); //dmg burn should be attack the armor first...
									PrintHintText(i,"You've been hit by a Fire Glaive!");
								}
							}
						}
						EmitSoundToAll(firesnd,attacker);
						EmitSoundToAll(firesnd,victim);							
					}
					if(  skill_level > 0 && GetRandomFloat( 0.0, 1.0 ) <= SunLanceChance[skill_level]) //calculate the chance...
					{
						//passiv attacker skill
						W3FlashScreen(attacker,RGBA_COLOR_RED);
						new Float:FatTony = GetRandomFloat(1.2,3.2);
						new Float:start_pos[3];
						new Float:target_pos[3];
						GetClientAbsOrigin(attacker,start_pos);
						GetClientAbsOrigin(victim,target_pos);
						target_pos[2]+=40.0;
						start_pos[2]+=45.0;
						TE_SetupBeamPoints(start_pos, target_pos, BeamSprite, HaloSprite, 0, 10, GetRandomFloat(0.8,1.4), FatTony, FatTony, 0, 2.5, {255,120,120,255}, 100);
						TE_SendToAll();
						TE_SetupGlowSprite(target_pos, FireSprite, GetRandomFloat(0.4,0.65), 0.80, 255 );
						TE_SendToAll();
						EmitSoundToAll(zitsch,attacker);
					}				
					//bSunShoot should be true when ability is used!
					if( bSunShoot[attacker] )
					{
						new Float:start_pos[3];
						new Float:target_pos[3];
						new Float:ParticleOffset[3] = {0.0, 0.0, 50.0};
						GetClientAbsOrigin(attacker,start_pos);
						GetClientAbsOrigin(victim,target_pos);
						target_pos[2]+=50.0;
						start_pos[2]+=60.0;

						TE_SetupBeamPoints(start_pos, target_pos, FireSprite, HaloSprite, 0, 100, GetRandomFloat(1.8,2.4), 5.0, 35.0, 0, 1.0, {255,100,100,255}, 100);
						TE_SendToAll();
						
						CreateTimer( 4.0, Timer_RemoveEntity, CreateParticleSystem(victim, "fire_medium_02", true, "grenade1", ParticleOffset) ); //fireball
						IgniteEntity(victim, 2.0);
						War3_DealDamage( victim, GetRandomInt(10,20), attacker, DMG_BURN, "sunlance" );
						bSunShoot[attacker]=false;
						EmitSoundToAll(firesnd,attacker);
					}
				}
				else
				W3MsgEnemyHasImmunity( victim, true );
			}
		}
	}
}

public OnWar3EventSpawn( client )
{
	bIncendium[client]=false;
	iManaValue[client]=0;
	new race = War3_GetRace( client );
	if( race == thisRaceID )
	PassiveSpawnSkills( client, true );
	if(bExtension) W3SetManaRegen(client,1); // Mleko
}

public PassiveSpawnSkills( client, bool:spawned )
{
	new skill = War3_GetSkillLevel( client, thisRaceID, SKILL_3 );
	if(spawned) {
		if(skill>0) {
			CreateTimer( 0.1, Timer_AttachEntity, client);
			/*new particle = CreateEntityByName("env_smokestack");
			if(IsValidEdict(particle) && IsClientInGame(client))
			{
				decl String:Name[32], Float:fPos[3];
				Format(Name, sizeof(Name), "W3S_particles_%i", client);
				GetEntPropVector(client, Prop_Send, "m_vecOrigin", fPos);
				fPos[2] += 30.0;
				DispatchKeyValueVector(particle, "Origin", fPos);
				DispatchKeyValueFloat(particle, "BaseSpread", 45.0);
				DispatchKeyValueFloat(particle, "StartSize", 15.0);
				DispatchKeyValueFloat(particle, "EndSize", 25.0);
				DispatchKeyValueFloat(particle, "Twist", 20.0);
				
				DispatchKeyValue(particle, "Name", Name);
				DispatchKeyValue(particle, "SmokeMaterial", "effects/strider_bulge_dudv.vmt");
				DispatchKeyValue(particle, "RenderColor", "255 255 255");
				DispatchKeyValue(particle, "SpreadSpeed", "25");
				DispatchKeyValue(particle, "RenderAmt", "200");
				DispatchKeyValue(particle, "JetLength", "120");
				DispatchKeyValue(particle, "RenderMode", "0");
				DispatchKeyValue(particle, "Initial", "0");
				DispatchKeyValue(particle, "Speed", "200");
				DispatchKeyValue(particle, "Rate", "60");
				DispatchSpawn(particle);
				SetVariantString("!activator");
				AcceptEntityInput(particle, "SetParent", client, particle, 0);
				AcceptEntityInput(particle, "TurnOn");
			}
			else
			LogError("Failed to create entity env_smokestack!");*/
		}
		new particle =  CreateParticleSystem(client, "fire_medium_01_glow", false, _, _);
		decl Float:fPos[3];
		GetClientAbsOrigin(client, fPos);
		fPos[2]+=50;
		TeleportEntity(particle, fPos, NULL_VECTOR, NULL_VECTOR);
		CreateTimer( 5.0, Timer_RemoveEntity, particle);
	}
}

public Action:Timer_AttachEntity( Handle:timer, any:client )
{
	CreateParticleSystem(client, "fire_small_base", true, "rfoot", _);
	CreateParticleSystem(client, "fire_small_base", true, "lfoot", _);
}

public Action:Timer_RemoveEntity( Handle:timer, any:particle )
{
	if( IsValidEdict( particle ))
	AcceptEntityInput( particle, "Kill" );
}

/*public Action:Timer_DisplayEnergy( Handle:timer, any:i )
{
	if(ValidPlayer(i,true))
		if(SunCharge[i]<=50)
			PrintCenterText(i,"Sun Energy : %i/50",SunCharge[i]);
}*/

//comment yourself...
public OnAbilityCommand(client,ability,bool:pressed)
{
	if(War3_GetRace(client)==thisRaceID && pressed && IsPlayerAlive(client)) //we dont need a ability key check, because we only have 1 ability...
	{
		new skill = War3_GetSkillLevel(client,thisRaceID,SKILL_1);
		if(skill > 0)
		{
			if(!Silenced(client) && War3_SkillNotInCooldown(client,thisRaceID,SKILL_1,true))
			{
				new old_mana = GetManaWrapper(client);
				if(old_mana>=15)
				{
					if(!bSunShoot[client]) {
						bSunShoot[client]=true;
					//	mana-=15;
						SetManaWrapper(client,old_mana-15);
						PrintHintText(client,"Sun Lance activated!");
						PrintToChat(client,"\x04[War3Source]\x01 You next shoot will release some Sun Energy");
						EmitSoundToAll(charge,client);
						W3FlashScreen(client,RGBA_COLOR_RED,1.0,0.5);
						War3_CooldownMGR(client,8.0,thisRaceID,SKILL_1,true,true);
					}
					else
					PrintHintText(client,"Sunlance is already active!");
				}
				else
				PrintHintText(client,"You do not have enough SunEnergy to do that!");
			}
		}
	}
}

public OnUltimateCommand( client, race, bool:pressed )
{
	if( race == thisRaceID && pressed && IsPlayerAlive( client ) && !Silenced( client ) )
	{
		new ult_level = War3_GetSkillLevel( client, race, ULT );
		if( ult_level > 0)
		{
			if( War3_SkillNotInCooldown( client, thisRaceID, ULT, true ) )
			{
				new old_mana = GetManaWrapper(client);
				if(old_mana>=20) {
					// mana-=20;
					SetManaWrapper(client,old_mana-20);
					EmitSoundToAll(ultimate,client);
					new Float:maxdist = SunRange[ult_level];
					decl Float:StartPos[3];
					GetClientAbsOrigin(client, StartPos);
					
					
					new Float:fPos[3], String:Name[32];
					GetEntPropVector(client, Prop_Send, "m_vecOrigin", fPos);
					fPos[2] += 320.0;
					Format(Name, sizeof(Name), "W3S_particles_%i", client);
					
					/*new particle = CreateEntityByName("env_smokestack");
					if(IsValidEdict(particle) && IsClientInGame(client))
					{
						new Float:fAngles[3] = {25.0, 110.0, 110.0};
						DispatchKeyValueVector(particle, "Origin", fPos);
						DispatchKeyValueVector(particle, "Origin", fAngles);
						DispatchKeyValueFloat(particle, "BaseSpread", 80.0);
						DispatchKeyValueFloat(particle, "StartSize", 30.0);
						DispatchKeyValueFloat(particle, "EndSize", 1.0);
						DispatchKeyValueFloat(particle, "Twist", 500.0);
						
						DispatchKeyValue(particle, "Name", Name);
						DispatchKeyValue(particle, "SmokeMaterial", "sprites/light_glow02_add_noz");
						DispatchKeyValue(particle, "RenderColor", "255 110 110");
						DispatchKeyValue(particle, "SpreadSpeed", "25");
						DispatchKeyValue(particle, "RenderAmt", "200");
						DispatchKeyValue(particle, "JetLength", "100");
						DispatchKeyValue(particle, "RenderMode", "0");
						DispatchKeyValue(particle, "Initial", "0");
						DispatchKeyValue(particle, "Speed", "200");
						DispatchKeyValue(particle, "Rate", "800");
						DispatchSpawn(particle);
						AcceptEntityInput(particle, "TurnOn");
					}
					else
					LogError("Failed to create entity env_smokestack!");*/
					TE_SetupBeamRingPoint(StartPos,10.0,maxdist,CoreSprite,HaloSprite,0,0,1.0,120.0,1.0,{ 255,120,120,255},0,0);
					TE_SendToAll(0.4);
					new particle2 = CreateEntityByName("env_smokestack");
					if(IsValidEdict(particle2) && IsClientInGame(client))
					{
						DispatchKeyValueVector(particle2, "Origin", fPos);
						DispatchKeyValueFloat(particle2, "BaseSpread", 80.0);
						DispatchKeyValueFloat(particle2, "StartSize", 20.0);
						DispatchKeyValueFloat(particle2, "EndSize", 10.0);
						DispatchKeyValueFloat(particle2, "Twist", 80.0);
						
						DispatchKeyValue(particle2, "Name", Name);
						DispatchKeyValue(particle2, "SmokeMaterial", "particle/fire.vmt");
						DispatchKeyValue(particle2, "RenderColor", "200 86 86");
						DispatchKeyValue(particle2, "SpreadSpeed", "600");
						DispatchKeyValue(particle2, "RenderAmt", "200");
						DispatchKeyValue(particle2, "JetLength", "600");
						DispatchKeyValue(particle2, "RenderMode", "0");
						DispatchKeyValue(particle2, "Initial", "0");
						DispatchKeyValue(particle2, "Speed", "200");
						DispatchKeyValue(particle2, "Rate", "500");
						DispatchSpawn(particle2);
						AcceptEntityInput(particle2, "TurnOn");
						CreateTimer( 6.0, Timer_RemoveEntity, particle2 );
					}
					else
					LogError("Failed to create entity env_smokestack!");

					TE_SetupGlowSprite(fPos, CoreSprite, 6.0, 2.8, 255);
					TE_SendToAll();
					
					for (new i = 1; i <= MaxClients; i++) {
						if(ValidPlayer(i,true) && GetClientTeam(i) != GetClientTeam(client)) {
							decl Float:TargetPos[3];
							GetClientAbsOrigin(i, TargetPos);
							new Float:Distance = GetVectorDistance(StartPos, TargetPos);
							if (Distance <= maxdist) {
								W3FlashScreen(i, RGBA_COLOR_RED, 1.6, 0.1);
								War3_DealDamage(i, GetRandomInt(SunMinDmg[ult_level],SunMaxDmg[ult_level]), client, DMG_BURN, "solaris" );
								PushClientToVector(i, fPos, -GetConVarFloat(cvar_solarispush) );
								PrintHintText(i, "You've been by Solaris!");
								TE_SetupBeamPoints(fPos, TargetPos, LaserSprite, HaloSprite, 0, 25, 2.0, 150.0, 200.0, 1, 2.0, {255,120,55,255}, 20);
								TE_SendToAll();
							}
						}
					}
					War3_CooldownMGR(client,GetConVarFloat(cvar_solariscd),thisRaceID,ULT,true,true);
				}
				else
				PrintHintText(client,"You do not have enough SunEnergy to do that!");
			}
		}
		else
		W3MsgUltNotLeveled( client );
	}
}

stock TE_SendToTeam(team,Float:delay=0.0)
{
	new total = 0;
	new clients[MaxClients];
	for (new i=1; i<=MaxClients; i++)
	{
		if (ValidPlayer(i,false)&&!IsFakeClient(i))
		{
			if(GetClientTeam(i)==team) {
				clients[total++] = i;
			}
		}
	}
	return TE_Send(clients, total, delay);
}
stock TE_SendToAllButTeam(team,Float:delay=0.0)
{
	new total = 0;
	new clients[MaxClients];
	for (new i=1; i<=MaxClients; i++)
	{
		if (ValidPlayer(i,false)&&!IsFakeClient(i))
		{
			if(GetClientTeam(i)!=team) {
				clients[total++] = i;
			}
		}
	}
	return TE_Send(clients, total, delay);
}

GetManaWrapper(client) {
	decl mana;
	if(bExtension) {
		mana = W3GetMana(client);
	}
	else {
		mana = iManaValue[client];
	}
	return mana;
}

SetManaWrapper(client,value) {
	if(bExtension) {
		W3SetMana(client,value);
	}
	else {
		iManaValue[client]=value;
	}
}

// ------------------------------------------------------------------------
// CreateParticleSystem()
// ------------------------------------------------------------------------
// >> Original code by J-Factor
// ------------------------------------------------------------------------
stock CreateParticleSystem(iClient, String:strParticle[], bool:bAttach = false, String:strAttachmentPoint[]="", Float:fOffset[3]={0.0, 0.0, 0.0})
{
    new iParticle = CreateEntityByName("info_particle_system");
    if (IsValidEdict(iParticle))
    {
        decl Float:fPosition[3];
        decl Float:fAngles[3];
        decl Float:fForward[3];
        decl Float:fRight[3];
        decl Float:fUp[3];
        
        // Retrieve entity's position and angles
        GetClientAbsOrigin(iClient, fPosition);
        GetClientAbsAngles(iClient, fAngles);
        
        // Determine vectors and apply offset
        GetAngleVectors(fAngles, fForward, fRight, fUp);    // I assume 'x' is Right, 'y' is Forward and 'z' is Up
        fPosition[0] += fRight[0]*fOffset[0] + fForward[0]*fOffset[1] + fUp[0]*fOffset[2];
        fPosition[1] += fRight[1]*fOffset[0] + fForward[1]*fOffset[1] + fUp[1]*fOffset[2];
        fPosition[2] += fRight[2]*fOffset[0] + fForward[2]*fOffset[1] + fUp[2]*fOffset[2];
        
        // Teleport and attach to client
        TeleportEntity(iParticle, fPosition, fAngles, NULL_VECTOR);
        DispatchKeyValue(iParticle, "effect_name", strParticle);

        if (bAttach == true)
        {
            SetVariantString("!activator");
            AcceptEntityInput(iParticle, "SetParent", iClient, iParticle, 0);            
            
            if (StrEqual(strAttachmentPoint, "") == false)
            {
                SetVariantString(strAttachmentPoint);
                AcceptEntityInput(iParticle, "SetParentAttachmentMaintainOffset", iParticle, iParticle, 0);                
            }
        }

        // Spawn and start
        DispatchSpawn(iParticle);
        ActivateEntity(iParticle);
        AcceptEntityInput(iParticle, "Start");
    }

    return iParticle;
}

public Action:PushClientToVector( victim, Float:pos1[3], Float:power )
{
	new Float:pos2[3], Float:main_origin[3], Float:velo1[3], Float:velo2[3];
	GetClientAbsOrigin( victim, pos2 );

	main_origin[0] = pos1[0] - pos2[0], main_origin[1] = pos1[1] - pos2[1], main_origin[2] = pos1[2] - pos2[2];
	velo1[0] += 0, velo1[1] += 0, velo1[2] += 300;
	
	velo2[0] = main_origin[0] * ( 100 * power );
	velo2[1] = main_origin[1] * ( 100 * power );
	velo2[2] = main_origin[2] * ( 100 * power );

	TeleportEntity(victim, NULL_VECTOR, NULL_VECTOR, velo1);
	TeleportEntity(victim, NULL_VECTOR, NULL_VECTOR, velo2);
}
